package org.hydrakyoufeng.stuplatform.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.concurrent.TimeUnit;

@Component
public class IpLimitInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.indexOf(",") != -1) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String ipLimitKey = "limit_ip:" + ip;
        // 判断当前IP是否被限制了
        Object value = redisTemplate.opsForValue().get(ipLimitKey);
        if (value != null) {
            response.getWriter().write("{\"code\":0,\"msg\":\"短时间请求次数过多\"}");
            return false;
        }
        String ipCountKey = "count_ip:" + ip;
        // 获取当前IP的请求次数
        Object count = redisTemplate.opsForValue().get(ipCountKey);
        if (null == count) {
            count = 1;
            redisTemplate.opsForValue().set(ipCountKey, 1, 60, TimeUnit.SECONDS);
        }
        int i = Integer.parseInt(count.toString()) + 1;
        // 一分钟内只能请求120次
        if (i >= 120) {
            response.getWriter().write("{\"code\":0,\"msg\":\"短时间请求次数过多\"}");
            // 请求次数过多限制5分中
            redisTemplate.opsForValue().set(ipLimitKey, 1, 5, TimeUnit.SECONDS);
            return false;
        }
        return true;
    }
}
